<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>new document</title>
    <meta name="generator" content="editplus"/>
    <meta name="author" content=""/>
    <meta name="keywords" content=""/>
    <meta name="description" content=""/>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <!-- <script src="jquery-2.0.3.min.js" type="text/javascript"></script> -->
</head>

<body>
<div style="width:300px; height: 300px; position: absolute; margin: 100px auto;left: 0;right: 0;">
    Welcome<br/>
    <input id="text" type="text"/>

    <button onclick="csend()">CopyText</button>

    <hr/>
    <button onclick="closeWebSocket()">关闭WebSocket连接</button>
    <hr/>
    <div id="message"></div>
</div>
</body>

<script type="text/javascript">
    var websocket = null;
    var url = "ws:\\127.0.0.1:8000/webSocket/"
    var sid = "002"
    var ws_url = url + sid
    // reConnect函数节流标识符
    let flag = true;
    //心跳机制
    let timeObj = null;
    let serverTimeObj = null;
    let heart = {
        timeOut: 10000,
        timeObj,
        serverTimeObj,
        start: function () {
            console.log('start');
            let self = this;
            //清除延时器
            this.timeObj && clearTimeout(this.timeObj);
            this.serverTimeObj && clearTimeout(this.serverTimeObj);
            this.timeObj = setTimeout(function () {
                websocket.send('hello,i am '+sid);//发送消息，服务端返回信息，即表示连接良好，可以在socket的onmessage事件重置心跳机制函数
                //定义一个延时器等待服务器响应，若超时，则关闭连接，重新请求server建立socket连接
                self.serverTimeObj = setTimeout(function () {
                    websocket.close();
                    reConnect(ws_url);
                }, self.timeOut)
            }, this.timeOut)
        }
    };

    //建立websocket连接函数
    function createWebsocket(url) {
        try {
            websocket = new WebSocket(url);
            init();
        } catch (e) {
            //进行重连;
            console.log('websocket连接错误');
            reConnect(ws_url);
        }
    }

    //判断当前浏览器是否支持WebSocket
    if ('WebSocket' in window) {
        //websocket = new WebSocket(ws_url+"?token="+token);
        createWebsocket(ws_url);
    } else {
        alert('当前浏览器 Not support websocket')
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //对WebSocket各种事件进行监听
    function init() {
        //连接发生错误的回调方法
        websocket.onerror = function () {
            reConnect(ws_url);
            setMessageInnerHTML("WebSocket连接发生错误");
        };
        //连接成功建立的回调方法
        websocket.onopen = function () {
            //连接已经打开
            //重置心跳机制
            setMessageInnerHTML("WebSocket连接成功");
            heart.start();
        };
        //接收到消息的回调方法
        websocket.onmessage = function (event) {
            setMessageInnerHTML(event.data);
            //收到消息表示连接正常，所以重置心跳机制
            heart.start();
        };
        //连接关闭的回调方法
        websocket.onclose = function () {
            setMessageInnerHTML("WebSocket连接关闭");
        };
    }

    //重连函数
    //因为重连函数会被socket事件频繁触发，所以通过函数节流限制重连请求发送
    function reConnect(url) {
        if (!flag) {
            return;
        }
        flag = false;
        setTimeout(function () {
            createWebsocket(url);
            flag = true;
        }, 3000)
    }

    //关闭WebSocket连接
    function closeWebSocket() {
        websocket.close();
    }

    //监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。
    window.onbeforeunload = function () {
        closeWebSocket()
    }

    //发送消息
    function csend() {
        var message = document.getElementById('text').value;
        websocket.send(message);
        alert("successful");
    }
</script>